package com.net.xpay.web.controller.common;

import com.alipay.api.AlipayApiException;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.net.common.exception.BusinessException;
import com.net.common.model.ResultData;
import com.net.common.util.SerializationUtil;
import com.net.xpay.alipay.PoseidonAlipayClient;
import com.net.xpay.common.domain.User;
import com.net.xpay.common.domain.UserShard;
import com.net.xpay.common.helper.RedisHelper;
import com.net.xpay.common.manager.UserManager;
import com.net.xpay.common.manager.UserShardManager;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.constant.RedisKey;
import com.net.xpay.core.domain.AlipayUser;
import com.net.xpay.core.enums.AlipayUserStatus;
import com.net.xpay.core.manager.AlipayUserManager;
import com.net.xpay.core.model.AlipayUserSearchModel;
import com.net.xpay.core.model.CommonAlipayAuthModel;
import com.net.shard.ShardUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 2020/6/28 09:46

 */
@RestController
@Slf4j
@RequestMapping("/common/alipay-auth")
@Api(tags = "公共/签约接口", description = "公共 签约接口 net")
public class CommonAlipayAuthController {


    @Autowired
    private UserManager userManager;

    @Autowired
    private UserShardManager userShardManager;

    @Autowired
    private AlipayUserManager alipayUserManager;

    @Autowired
    private PoseidonAlipayClient xpayAlipayClient;

    @Autowired
    private RedisHelper redisHelper;

    /**
     * 获取支付宝授权页面, 可进行签约
     */
    @ApiOperation(value = "跳转支付宝签约页面")
    @PostMapping("/go-auth-page")
    @ResponseBody
    public ResultData<String> goAuthPage(@RequestBody CommonAlipayAuthModel authModel) throws AlipayApiException {
        log.info("common goAuthPage|params={}", SerializationUtil.obj2String(authModel));
        if (Strings.isNullOrEmpty(authModel.getAlipayNickName())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请输入支付宝账号");
        }
        if (Strings.isNullOrEmpty(authModel.getUid())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "付款链接有误");
        }

        User user = userManager.findByUid(authModel.getUid());
        if (user == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "付款链接有误");
        }
        Preconditions.checkArgument(user.getUid().equals(authModel.getUid()));

        UserShard userShard = userShardManager.getById(user.getId());
        try {
            ShardUtil.setShardContext(userShard.getShardId());
            return new ResultData<>(doAlipayAuth(authModel.getAlipayNickName(), user));
        } finally {
            ShardUtil.cleanShardContext();
        }
    }

    private String doAlipayAuth(String alipayNickName, User user) throws AlipayApiException {
        Long userId = user.getId();
        //先从缓存中查，如果没有再请求新的
        Object authUrl = redisHelper.get(RedisKey.AUTH_ALIPAY_USER_URL + ":" + user.getId() + ":" + alipayNickName);
        if (authUrl != null) {
            AlipayUser alipayUser = alipayUserManager.findByAlipayNickName(user.getId(), alipayNickName);
            if (alipayUser != null) {
                alipayUser.setIsDeleted(0);
                alipayUserManager.updateByPrimaryKeyWithVersion(alipayUser);
            }
            return authUrl.toString();
        }

        String isvBizId = userId + "-" + System.currentTimeMillis();
        String authPageUrl = xpayAlipayClient.alipayOpenInviteOrderCreate(isvBizId, alipayNickName, "");

        AlipayUser alipayUser = alipayUserManager.findByAlipayNickName(userId, alipayNickName);
        if (alipayUser == null) {
            alipayUser = AlipayUser.getInstance();
            alipayUser.setUserId(userId);
            alipayUser.setMobile(user.getMobile());
            alipayUser.setAlipayNickName(alipayNickName);
            // 异步消息需要根据isvBizId来获取对应token
            alipayUser.setIsvBizId(isvBizId);
            alipayUser.setStatus(AlipayUserStatus.NO);
            alipayUser.setIsDeleted(0);
            alipayUserManager.save(alipayUser);

            //将第一个绑定的号作为主支付宝账号
            AlipayUserSearchModel searchModel = new AlipayUserSearchModel();
            searchModel.setUserId(user.getId());
            long count = alipayUserManager.searchCount(searchModel);
            if (count == 1L) {
                User selectedUser = userManager.getById(user.getId());
                selectedUser.setAlipayNickName(alipayNickName);
                selectedUser.setAlipayUserId(alipayUser.getId());
                userManager.updateByPrimaryKeyWithVersion(selectedUser);
            }
        } else {
            alipayUser.setIsvBizId(isvBizId);
            alipayUser.setIsDeleted(0);
            alipayUserManager.updateByPrimaryKeyWithVersion(alipayUser);
        }

        redisHelper.set(RedisKey.AUTH_ALIPAY_USER_URL + ":" + user.getId() + ":" + alipayNickName, authPageUrl, 60 * 30L);
        return authPageUrl;
    }

}
